package com.wsdk.util;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.support.v4.content.ContextCompat;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.view.View;

import com.wsdk.Wsdk;
import com.wsdk.bean.VersionStateData;
import com.wsdk.bean.WarnBean;
import com.wsdk.constants.GlobalData;
import com.wsdk.constants.UrlConstants;
import com.wsdk.exception.WsdkException;
import com.wsdk.service.BluetoothLeService;
import com.wsdk.util.StampUtil.StampCallback;
import com.wsdk.view.ProcessDialog;

import org.json.JSONException;
import org.json.JSONObject;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Random;

/**
 * StampUtilFull
 *
 * @author fionera
 * @date 2018/6/25 in mobile_seal_android
 */
public class StampFullUtil
        implements BlueToothScanUtil.StopSearchListener {
    private static final int OPEN_BLUE_DIALOG = 1000;

    private Activity activity;
    private Context mContext;

    private boolean isTimeLimit;

    private ProcessDialog mProcessDialog;

    private StampCallback stampCallback;

    public void setStampCallback(StampCallback stampCallback) {
        this.stampCallback = stampCallback;
    }

    private boolean isNoNeedDealWithResetKey;

    public void setNoNeedDealWithResetKey(boolean noNeedDealWithResetKey) {
        isNoNeedDealWithResetKey = noNeedDealWithResetKey;
    }

    /**
     * common update logic
     */
    private ControlUtil controlUtil = new ControlUtil();

    private void checkVersion() {
        if (!GlobalData.isConnect) {
            blueToothScanUtil.setMacAddress(macAddress);
            blueToothScanUtil.startSearchBlueDevice();
        } else {
            controlUtil.checkVersion();
        }
    }

    private String hasNewVersion;

    private BroadcastReceiver updateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (BluetoothLeService.ACTION_GATT_HARDWARE_CONNECTED.equals(action)) {
                GlobalData.isConnect = true;
                checkVersion();
            } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
                byte[] data = intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA);
                if (ParseBluetoothData.isCheckVersion(data)) {
                    VersionStateData versionStateData = ParseBluetoothData.parseVersion(data);
                    if (versionStateData != null) {
                        String firmVersion = versionStateData.getFirmwareVersion();
                        initialStatus = versionStateData.getInitialStatus();
                        GlobalData.versionV2 = firmVersion.startsWith("02");
                        checkFirmWareUpdate(firmVersion);
                    }
                } else if (ParseBluetoothData.isSycTime(data)) {
                    // sync time
                    if (ParseBluetoothData.parseSyncTime(data)) {
                        GlobalData.selfCheckStatus = "0";
                        if (GlobalData.versionV2) {
                            feedbackToServerAndChooseUpdateMethod();
                        } else {
                            chooseUpdateMethod();
                        }
                    } else {
                        LogUtil.e("sync tim failed");
                        BluetoothLeService.disconnect();
                    }
                } else if (!isNoNeedDealWithResetKey && ParseBluetoothData.isInit(data)) {
                    // reset key
                    int ret;
                    if ((ret = ParseBluetoothData.parseInit(data)) == 0) {
                        syncTimeV1();
                    } else if (ret == 1) {
                        feedbackToServerAndFetchFourKey();
                    } else if (ret == 2) {
                        feedbackToServerAndSyncTime();
                    } else {
                        ShowToast.shortTime("重置key失败");
                    }
                }
            }
        }
    };

    private BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
                mProcessDialog.dismiss();
                GlobalData.isConnect = true;
            } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
                ShowToast.shortTime("蓝牙已断开，请重新连接后完成用印");
                stampCallback.onErrorCallback(StampCallback.ERR_STAMP_DISCONNECTED, "");
            } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
                byte[] data = intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA);
                if (ParseBluetoothData.parseOpenByte(data) == 0x00) {
                    ShowToast.shortTime("可以用印");
                } else if (ParseBluetoothData.parseOpenByte(data) == 0xec) {
                    ShowToast.shortTime("请先将信印复位");
                    stampCallback.onErrorCallback(StampCallback.ERR_STAMP_NEED_RESET, "");
                } else if (ParseBluetoothData.parseOpenByte(data) == 0xeb) {
                    GlobalData.hasAlarm = true;
                    // 上传报警信息
                    toUploadAlertTime(data);
                } else if(ParseBluetoothData.parseOpenByte(data) == 0xf4){
                    ShowToast.shortTime("开锁错误");
                    if(isTimeLimit) {
                        stampCallback.onErrorCallback(StampCallback.ERR_STAMP_ROLLBACK_PROGRESS, "");
                    } else {
                        sendRequestToRollbackStamp();
                    }
                } else if (ParseBluetoothData.parseDeleteAlert(data)) {
                    GlobalData.hasAlarm = false;
                    new ControlUtil().stamp();
                } else if (data[3] == 0x0f && data[4] != 0x00) {
                    ShowToast.shortTime("开锁失败");
                    if (isTimeLimit) {
                        stampCallback.onErrorCallback(StampCallback.ERR_STAMP_ROLLBACK_PROGRESS,
                                "");
                    } else {
                        sendRequestToRollbackStamp();
                    }
                } else if (ParseBluetoothData.isStampReturn(data)) {
                    if (ParseBluetoothData.parseStampReturn(data) == 0x00||
                            ParseBluetoothData.parseStampReturn(data) == 0x04) {
                        if (isTimeLimit) {
                            stampCallback.onSucessCallback(StampCallback.ERR_STAMP_SUCCESS, "");
                        } else {
                            // need deal with duplicated put in
                            if (!recordIds.contains(sealRecordId)) {
                                recordIds.add(sealRecordId);
                            }
                            stampCallback.onSucessCallback(StampCallback.ERR_STAMP_SUCCESS, "");
                            if (ParseBluetoothData.parseStampReturn(data) == 0x04) {
                                WarnBean warnBean = new WarnBean();
                                warnBean.setProcessFlag("0");
                                warnBean.setProcessId(sealApplyId);
                                warnBean.setAlarmMsg("非法用印" + String.valueOf(ParseBluetoothData
                                        .parseStampReturn(data)));
                                warnBean.setLatitude(String.valueOf(latitude));
                                warnBean.setLongitude(String.valueOf(latitude));
                                warnBean.setAlarmLocation(locationName);
                                warnBean.setCompanyCode("");

                                sendRequestWithResultToAlert(warnBean);
                            }
                            sendRequestWithResultToStamp();
                        }
                    } else if (ParseBluetoothData.parseStampReturn(data) == (byte) 0xff) {
                        ShowToast.shortTime("用印失败");
                        stampCallback.onErrorCallback(StampCallback.ERR_STAMP_INVALID, "");
                    } else {
                        ShowToast.shortTime("用印异常");
                        stampCallback.onErrorCallback(StampCallback.ERR_STAMP_UNKNOWN, "");
                    }
                } else if (ParseBluetoothData.isGetSN(data)) {
                    byte[] fetchSn = new byte[15];
                    System.arraycopy(data, 5, fetchSn, 0, 15);
                    sn = ParseBluetoothData.bytesToSn(fetchSn);
                    if (longitude == null || latitude == null || locationName == null) {
                        ShowToast.shortTime("获取定位信息失败\n请重新操作或重启章务通");
                        return;
                    }
                    if (isTimeLimit) {
                        if (compareDate(endTime)) {
                            stampCallback.onProgressCallback(
                                    StampCallback.ERR_STAMP_PREPARE_PROGRESS, "");
                            sendRequestToStamp();
                        } else {
                            ShowToast.shortTime("超过用印时间，不能用印");
                        }
                    } else {
                        if (remainTimes > 0) {
                            stampCallback.onProgressCallback(
                                    StampCallback.ERR_STAMP_PREPARE_PROGRESS, "");
                            sendRequestToStamp();
                        } else {
                            ShowToast.shortTime("剩余次数为0，不能用印");
                        }
                    }
                }
            }
        }
    };

    private String macAddress;
    private String sn;
    private String sealApplyId;
    private String sealRecordId;
    private String rollbackKey;
    private int remainTimes;

    private String startTime = null;
    private String endTime = null;

    private BlueToothScanUtil blueToothScanUtil;

    private ArrayList<String> recordIds = new ArrayList<>();

    private Double longitude = null;
    private Double latitude = null;
    private String locationName = null;

    private StampFullUtil(Activity activity) throws WsdkException {
        if (activity != null) {
            this.activity = activity;
            mContext = activity;
            mProcessDialog = new ProcessDialog(activity);
            blueToothScanUtil = new BlueToothScanUtil(activity);
            initBroadCast();
            dealWithUpdate();
            fetchGlobalCode();
        } else {
            throw new IllegalArgumentException("Activity cannot be null");
        }
    }

    public StampFullUtil(Activity activity, StampCallback stampCallback) throws WsdkException {
        this(activity);
        this.stampCallback = stampCallback;
    }

    private void initBroadCast() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
        mContext.registerReceiver(bluetoothReceiver, intentFilter);
    }

    private void dealWithUpdate() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_HARDWARE_CONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
        intentFilter.addAction(BluetoothLeService.ACTION_DEVICE_UPLEVEL_FAILED);
        mContext.registerReceiver(updateReceiver, intentFilter);
    }

    private String globalCode = "";

    @SuppressLint({"HardwareIds"})
    private void fetchGlobalCode() {
        String imei = null;
        if (ContextCompat.checkSelfPermission(activity,
                Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            imei = new Random().toString();
            globalCode = imei + System.currentTimeMillis();
            return;
        }
        TelephonyManager telephonyManager = (TelephonyManager) activity.getSystemService(
                Context.TELEPHONY_SERVICE);
        if (telephonyManager != null) {
            imei = telephonyManager.getDeviceId();
        }
        if (imei == null) {
            imei = new Random().toString();
        }
        globalCode = imei + System.currentTimeMillis();
    }

    private boolean checkBleUnOpened() {
        boolean opened = BlueToothScanUtil.isBlueToothOpened();
        if (!opened) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            activity.startActivityForResult(enableBtIntent, OPEN_BLUE_DIALOG);
        }
        return !opened;
    }

    public void stamp() {
        if (checkBleUnOpened()) {
            return;
        }
        if (GlobalData.isConnect) {
            if (isTimeLimit) {
                if ("0".equals(GlobalData.selfCheckStatus)) {
                    if (!compareDate(endTime) && GlobalData.hasAlarm) {
                        stampCallback.onProgressCallback(StampCallback.ERR_STAMP_PREPARE_PROGRESS, "");
                        new ControlUtil().stamp();
                    } else {
                        new ControlUtil().getSN();
                    }
                } else {
                    ShowToast.shortTime("设备异常，请联系管理员! ");
                }
            } else {
                if ("0".equals(GlobalData.selfCheckStatus)) {
                    if (GlobalData.hasAlarm) {
                        stampCallback.onProgressCallback(StampCallback.ERR_STAMP_PREPARE_PROGRESS, "");
                        new ControlUtil().stamp();
                    } else {
                        new ControlUtil().getSN();
                    }
                } else {
                    ShowToast.shortTime("设备异常，请联系管理员");
                }
            }
        } else {
            /*
              not connected
             */
            if (Wsdk.isUseEmbedLogic()) {
                ShowDialog.showSelectDialog(mContext, "重新连接蓝牙", "蓝牙未连接，请先连接蓝牙", "", new View
                        .OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mProcessDialog.setTitle("正在连接蓝牙").showNormal();
                        blueToothScanUtil.setMacAddress(macAddress);
                        blueToothScanUtil.startSearchBlueDevice();
                        blueToothScanUtil.setStopSearchListener(StampFullUtil.this);
                    }
                });
            }
            stampCallback.onErrorCallback(StampCallback.ERR_STAMP_NONE_BLE_CONNECTION, "");
        }
    }

    public void release() {
        mContext.unregisterReceiver(bluetoothReceiver);
        mContext.unregisterReceiver(updateReceiver);
        OkHttpUtil.cancelCallWithTag("OkHttpCall_" + this.hashCode());
        stampCallback = null;
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == OPEN_BLUE_DIALOG && resultCode == Activity.RESULT_CANCELED) {
            stampCallback.onErrorCallback(StampCallback.ERR_STAMP_NONE_BLE_OPEN, "");
        }
    }

    private void getEnqueue(String url, OkHttpUtil.NetCallBack responseCallback) {
        OkHttpUtil.getEnqueue(url, responseCallback, "OkHttpCall_" + this.hashCode());
    }

    private void postJsonEnqueue(String url, Map<String, String> params,
                                   OkHttpUtil.NetCallBack responseCallback) {
        OkHttpUtil.postJsonEnqueue(url.contains(
                "?") ? (url + "&reqIdentifer=" + globalCode) : (url + "?reqIdentifer=" + globalCode),
                params, responseCallback, "OkHttpCall_" + this.hashCode());
    }

    protected void postJsonEnqueueWithoutBaseUrl(String url, Map<String, String> params,
                                                 OkHttpUtil.NetCallBack responseCallback) {
        OkHttpUtil.postJsonEnqueueWithoutBaseUrl(url.contains(
                "?") ? (url + "&reqIdentifer=" + globalCode) : (url + "?reqIdentifer=" + globalCode),
                params, responseCallback, "OkHttpCall_" + this.hashCode());
    }

    protected void putJsonEnqueue(String url, Map<String, String> params,
                                  OkHttpUtil.NetCallBack responseCallback) {
        OkHttpUtil.putJsonEnqueue(url, params, responseCallback, "OkHttpCall_" + this.hashCode());
    }

    protected void deleteJsonEnqueue(String url, Map<String, String> params,
                                     OkHttpUtil.NetCallBack responseCallback) {
        OkHttpUtil.deleteJsonEnqueue(url, params, responseCallback,
                "OkHttpCall_" + this.hashCode());
    }

    /**
     * 检查版本是否存在新版本
     * @param firmVersion firmVersion
     */
    private void checkFirmWareUpdate(final String firmVersion) {
        controlUtil = new ControlUtil(GlobalData.versionV2);
        LogUtil.d("Bluetooth Firm Update Check");
        Map<String, String> param = new HashMap<>();
        param.put("flag", "0");
        param.put("firmwareVersion", firmVersion);
        param.put("equipSn", sn);
        postJsonEnqueue(UrlConstants.FIRMWARE_VERSION, param, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                try {
                    JSONObject data = new JSONObject(json);
                    hasNewVersion = data.optString(
                            "firmhasNewVersion");
                    if (isNoNeedDealWithResetKey) {
                        if (GlobalData.versionV2) {
                            controlUtil.getSN();
                        } else {
                            syncTimeV1();
                        }
                    } else {
                        if (GlobalData.versionV2) {
                            String resetRepairKey = data.optString("resetRepairKey");
                            String resetKey = data.optString("resetKey");
                            String isInner = data.optString("equipType");
                            if (TextUtils.equals("1", resetRepairKey)) {
                                // reset repair
                                if (TextUtils.equals("0", isInner)) {
                                    ShowDialog.showConfirmDialog(mContext, "恢复工作模式",
                                            "检测到固件当前处于维修模式\n但设备无法通过SDK恢复\n请使用章盾进行恢复",
                                            new View.OnClickListener() {
                                                @Override
                                                public void onClick(View v) {
                                                    BluetoothLeService.disconnect();
                                                }
                                            });
                                } else {
                                    fetchMKeyForInit();
                                }
                            } else if (TextUtils.equals("1", resetKey)) {
                                fetchMKeyForInit();
                            } else {
                                syncTimeV2();
                            }
                        } else {
                            syncTimeV1();
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime(reason);
                BluetoothLeService.disconnect();
            }
        });
    }

    private void syncTimeV1() {
        getEnqueue(UrlConstants.GET_SERVER_TIME, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                try {
                    JSONObject jsonObject = new JSONObject(json);
                    String returnData = jsonObject.getString("sysDatime");
                    //获取服务器时间，发送同步时间指令
                    new ControlUtil(false).sysServerTime(returnData);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime("获取服务器时间失败");
                new ControlUtil(false).sycTime();
            }
        });
    }

    private String initialStatus;
    private String firstMKey;
    private String secondMKey;
    private String firstWKey;
    private String secondWKey;

    /**
     * fetch mkey init1
     */
    private void fetchMKeyForInit() {
        firstMKey = "";
        secondMKey = "";
        firstWKey = "";
        secondWKey = "";
        HashMap<String, String> params = new HashMap<>();
        params.put("equipActualSn", sn);
        postJsonEnqueue(UrlConstants.FETCH_MAINTAIN_KEY, params, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                try {
                    JSONObject jsonObject = new JSONObject(json);
                    firstMKey = jsonObject.getString("firstMkey");
                    secondMKey = jsonObject.getString("secondMkey");
                    String tmpFirstMKey = secondMKey;
                    new ControlUtil().init1(
                            firstMKey,
                            TextUtils.equals("02", initialStatus) ? tmpFirstMKey : secondMKey, sn);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime(reason);
            }
        });
    }

    /**
     * feedback2server then fetch four init2
     */
    private void feedbackToServerAndFetchFourKey() {
        HashMap<String, String> params = new HashMap<>();
        params.put("equipActualSn", sn);
        params.put("firstMKey", firstMKey);
        params.put("secondMKey", secondMKey);
        params.put("firstWKey", firstWKey);
        params.put("secondWKey", secondWKey);
        postJsonEnqueue(UrlConstants.VERIFY_MAINTAIN_KEY, params, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                fetchFourKeyForInit();
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime(reason);
            }
        });
    }

    /**
     * fetch four init2
     */
    private void fetchFourKeyForInit() {
        getEnqueue(String.format(Locale.CHINA, UrlConstants.FETCH_FOUR_KEY, sn), new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                try {
                    JSONObject jsonObject = new JSONObject(json);
                    firstMKey = jsonObject.getString("firstMKey");
                    secondMKey = jsonObject.getString("secondMKey");
                    firstWKey = jsonObject.getString("firstWKey");
                    secondWKey = jsonObject.getString("secondWKey");
                    new ControlUtil().init2(firstMKey, secondMKey, firstWKey, secondWKey, sn);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime(reason);
            }
        });
    }

    /**
     * feedback2server then fetch syncv2
     */
    private void feedbackToServerAndSyncTime() {
        HashMap<String, String> params = new HashMap<>();
        params.put("equipActualSn", sn);
        params.put("firstMKey", firstMKey);
        params.put("secondMKey", secondMKey);
        params.put("firstWKey", firstWKey);
        params.put("secondWKey", secondWKey);
        postJsonEnqueue(UrlConstants.VERIFY_MAINTAIN_KEY, params, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                syncTimeV2();
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime(reason);
            }
        });
    }

    private void syncTimeV2() {
        getEnqueue(String.format(Locale.CHINA, UrlConstants.FETCH_WORK_KEY, sn),
                new OkHttpUtil.NetCallBack() {
                    @Override
                    public void onSucceed(String json) {
                        try {
                            JSONObject jsonObject = new JSONObject(json);
                            firstWKey = jsonObject.getString("firstWKey");
                            secondWKey = jsonObject.getString("secondWKey");
                            String timeStamp = jsonObject.getString("timeStamp");
                            // 获取服务器时间，发送同步时间指令
                            new ControlUtil().connect(firstWKey, secondWKey, sn, timeStamp);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void onFailed(String reason) {
                        ShowToast.shortTime("获取服务器时间失败");
                        BluetoothLeService.disconnect();
                    }
                });
    }

    private void feedbackToServerAndChooseUpdateMethod() {
        HashMap<String, String> params = new HashMap<>();
        params.put("equipActualSn", sn);
        params.put("firstWKey", firstWKey);
        params.put("secondWKey", secondWKey);
        postJsonEnqueue(UrlConstants.VERIFY_MAINTAIN_KEY, params, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                chooseUpdateMethod();
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime(reason);
            }
        });
    }

    private void feedbackToServerForRepair() {
        getEnqueue(String.format(Locale.CHINA, UrlConstants.RESET_REPAIR_STATUS, sn), new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {

            }

            @Override
            public void onFailed(String reason) {

            }
        });
    }

    private void chooseUpdateMethod() {
        switch (hasNewVersion) {
            case "1":
                ShowDialog.showConfirmDialog(mContext, "固件升级",
                        "检测到固件有新版本\n但设备无法通过SDK升级\n请使用章务通进行升级",
                        new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                BluetoothLeService.disconnect();
                            }
                        });
                break;
            case "2":
                ShowDialog.showConfirmDialog(mContext, "固件升级",
                        "检测到固件有新版本\n但设备无法通过蓝牙升级\n请使用章盾进行升级",
                        new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                BluetoothLeService.disconnect();
                            }
                        });
                break;
            default:
                if (GlobalData.versionV2) {
                    mContext.sendBroadcast(new Intent(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED));
                } else {
                    ShowToast.shortTime("新版本不支持该固件,请联系管理员发布新固件");
                    BluetoothLeService.disconnect();
                }
                break;
        }
    }

    private boolean compareDate(String endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.CHINA);
        try {
            Date endDate = sdf.parse(endTime);
            Date nowDate = new Date();
            return nowDate.getTime() > endDate.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return false;
    }

    public void prepareStampEnv() {
        mProcessDialog.setTitle("正在获取用印次数").showNormal();
        getEnqueue(String.format(Locale.CHINA, UrlConstants.GET_STAMP_REMAIN_TIMES_NEW, sealApplyId),
                new OkHttpUtil.NetCallBack() {
                    @Override
                    public void onSucceed(String json) {
                        mProcessDialog.dismiss();

                        try {
                            JSONObject object = new JSONObject(json);
                            if (isTimeLimit) {
                                stampCallback.onTimeLimitCallback(0, startTime, endTime);
                            } else {
                                remainTimes = Integer.parseInt(object.optString("remainTimes"));
                                stampCallback.onRemainTimesCallback(0, remainTimes);
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                        if (checkBleUnOpened()) {
                            return;
                        }

                        if (!GlobalData.isConnect) {
                            mProcessDialog.setTitle("正在连接蓝牙").showNormal();
                            blueToothScanUtil.setMacAddress(macAddress);
                            blueToothScanUtil.startSearchBlueDevice();
                            blueToothScanUtil.setStopSearchListener(StampFullUtil.this);
                        }
                    }

                    @Override
                    public void onFailed(String reason) {
                        mProcessDialog.dismiss();
                        ShowToast.shortTime(reason);
                        stampCallback.onErrorCallback(StampCallback.ERR_STAMP_GET_TIMES_FAILED, reason);
                    }
                });
    }

    private void sendRequestToStamp() {
        Map<String, String> params = new HashMap<>();
        params.put("sealApplyId", sealApplyId);
        params.put("longtitude", String.valueOf(longitude));
        params.put("latitude", String.valueOf(latitude));
        params.put("locationName", locationName);
        params.put("authorityTimes", String.valueOf(remainTimes));
        postJsonEnqueue(UrlConstants.STAMP, params, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                try {
                    JSONObject object = new JSONObject(json);
                    sealApplyId = object.optString("sealApplyId");
                    if (!isTimeLimit) {
                        sealRecordId = object.optString("sealRecordId");
                        rollbackKey = object.optString("rollbackKey");
                        remainTimes = Integer.parseInt(object.optString("remainTimes"));
                    }

                    new ControlUtil().stamp();

                    stampCallback.onRemainTimesCallback(1, remainTimes);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime(reason);
                stampCallback.onErrorCallback(StampCallback.ERR_STAMP_AUTHORITY_FAILED, reason);
            }
        });
    }

    private void sendRequestWithResultToStamp() {
        Map<String, String> param = new HashMap<>();
        param.put("sealRecordId", sealRecordId);
        postJsonEnqueue(UrlConstants.STAMP_RESULT, param, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                ShowToast.shortTime("盖章结果已上报");
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime(reason);
            }
        });
    }

    private void sendRequestToRollbackStamp() {
        mProcessDialog.setTitle("正在回滚授权").showNormal();
        Map<String, String> param = new HashMap<>();
        param.put("sealRecordId", sealRecordId);
        param.put("rollbackKey", rollbackKey);
        postJsonEnqueue(UrlConstants.STAMP_ROLLBACK, param, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                mProcessDialog.dismiss();
                try {
                    JSONObject jsonObject = new JSONObject(json);
                    remainTimes = Integer.parseInt(jsonObject.optString("remainTimes"));
                } catch (Exception e) {
                    e.printStackTrace();
                }

                stampCallback.onErrorCallback(StampCallback.ERR_STAMP_ROLLBACK_PROGRESS, "");
            }

            @Override
            public void onFailed(String reason) {
                mProcessDialog.dismiss();
                ShowDialog.showSelectDialog(mContext, "回滚失败", "回滚失败，是否重试", "取消回滚将视为放弃本次用印",
                        new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                sendRequestToRollbackStamp();
                            }
                        }, new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                stampCallback.onErrorCallback(StampCallback.ERR_STAMP_ROLLBACK_PROGRESS_IGNORE, "");
                            }
                        });
            }
        });
    }

    private void sendRequestWithResultToAlert(WarnBean warnBean) {
        Map<String, String> param = new HashMap<>();
        param.put("processFlag", warnBean.getProcessFlag());
        param.put("processId", warnBean.getProcessId());
        param.put("alarmMsg", warnBean.getAlarmMsg());
        param.put("latitude", warnBean.getLatitude());
        param.put("longitude", warnBean.getLongitude());
        param.put("alarmLocation", warnBean.getAlarmLocation());
        postJsonEnqueue(UrlConstants.STAMP_ALERT, param, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
            }

            @Override
            public void onFailed(String reason) {
            }
        });
    }

    /**
     * 上传报警起止时间
     */
    private void toUploadAlertTime(byte[] data){
        byte[] startTime = new byte[7];
        System.arraycopy(data, 5, startTime, 0, 7);
        byte[] endTime = new byte[7];
        System.arraycopy(data, 12, endTime, 0, 7);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA);
        try {
            Date dateStart = simpleDateFormat.parse(ControlUtil.bytesToHexString(startTime));
            Date dateEnd = simpleDateFormat.parse(ControlUtil.bytesToHexString(endTime));
            Map<String, String> params = new HashMap<>(10);
            params.put("processFlag", "0");
            params.put("ascSn", sn);
            params.put("alarmTimeStart", String.valueOf(dateStart.getTime()));
            params.put("alarmTimeEnd", String.valueOf(dateEnd.getTime()));
            params.put("latitude", String.valueOf(latitude));
            params.put("longitude", String.valueOf(longitude));
            params.put("alarmLocation", locationName);
            params.put("companyCode", "");
            postJsonEnqueue(UrlConstants.UPLOAD_ALERT, params, new OkHttpUtil.NetCallBack() {
                @Override
                public void onSucceed(String json) {
                    new ControlUtil().deleteAlert();
                }

                @Override
                public void onFailed(String reason) {
                    if ("没有找到用印记录".equals(reason)) {
                        new ControlUtil().deleteAlert();
                    }
                    stampCallback.onErrorCallback(StampCallback.ERR_STAMP_NO_RELATED_AUTHORITY, "");
                }
            });
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onStopped(boolean timeout) {
        mProcessDialog.dismiss();
        if (timeout) {
            ShowToast.shortTime("连接设备失败");
            stampCallback.onErrorCallback(StampCallback.ERR_STAMP_CONNECT_TIMEOUT, "");
        }
    }

    public String getSealApplyId() {
        return sealApplyId;
    }

    public void setSealApplyId(String sealApplyId) {
        this.sealApplyId = sealApplyId;
    }

    public String getMacAddress() {
        return macAddress;
    }

    public void setMacAddress(String macAddress) {
        this.macAddress = macAddress;
    }

    public String getSn() {
        return sn;
    }

    public void setSn(String sn) {
        this.sn = sn;
    }

    public String getStartTime() {
        return startTime;
    }

    public void setStartTime(String startTime) {
        this.startTime = startTime;
        isTimeLimit = true;
    }

    public String getEndTime() {
        return endTime;
    }

    public void setEndTime(String endTime) {
        this.endTime = endTime;
        isTimeLimit = true;
    }

    public void setLongitude(Double longitude) {
        this.longitude = longitude;
    }

    public void setLatitude(Double latitude) {
        this.latitude = latitude;
    }

    public void setLocationName(String locationName) {
        this.locationName = locationName;
    }

    public ArrayList<String> getRecordIds() {
        return recordIds;
    }
}
